package com.sub.util;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.github.junrar.Archive;
import com.github.junrar.rarfile.FileHeader;

/**
 * @Description: TODO(使用junrar实现rar解压)
 * @author wangkai
 * @date 2018年6月12日
 *
 */
public class UnRar {
	private static final Logger log = LoggerFactory.getLogger(UnRar.class);

	/**
	 * 压缩文件
	 * 
	 * @param srcfile(需要压缩文件)
	 * @param zipfile(压缩文件)
	 */
	public static void ZipFiles(String srcfile, String zipfile) {
		File file = new File(srcfile);
		byte[] buf = new byte[1024];
		File zipFile = new File(zipfile);
		if (!zipFile.exists()) {
			if (!zipFile.getParentFile().exists()) {
				zipFile.getParentFile().mkdirs();
			}
			try {
				zipFile.createNewFile();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		if (file.isDirectory()) {// 压缩指定文件夹下所有文件
			File[] files = file.listFiles();
			try {
				ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
				for (int i = 0; i < files.length; i++) {
					FileInputStream in = new FileInputStream(files[i]);
					out.putNextEntry(new ZipEntry(files[i].getName()));
					int len;
					while ((len = in.read(buf)) > 0) {
						out.write(buf, 0, len);
					}
					out.closeEntry();
					in.close();
				}
				out.close();
				System.out.println("压缩完成.");
			} catch (IOException e) {
				e.printStackTrace();
			}
		} else {// 压缩指定文件
			try {
				ZipOutputStream out = new ZipOutputStream(new FileOutputStream(zipFile));
				FileInputStream in = new FileInputStream(file);
				out.putNextEntry(new ZipEntry(file.getName()));
				int len;
				while ((len = in.read(buf)) > 0) {
					out.write(buf, 0, len);
				}
				out.closeEntry();
				in.close();
				out.close();
				System.out.println("压缩完成.");
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
	}
	/**
	 * 文件解压
	 * 
	 * @param srcRarPath(文件路径)
	 * @param dstDirectoryPath(解压路径)
	 * @throws Exception
	 */
	public static void unRar(String srcRarPath, String dstDirectoryPath) throws Exception {
		if (!srcRarPath.toLowerCase().endsWith(".rar")) {
			log.error("非rar文件！");
			return;
		}
		File dstDiretory = new File(dstDirectoryPath);
		if (!dstDiretory.exists()) {// 目标目录不存在时，创建该文件夹
			dstDiretory.mkdirs();
		}
		File fol = null;
		File out = null;
		Archive a = null;
		try {
			a = new Archive(new File(srcRarPath));
			if (a != null) {
				a.getMainHeader().print(); // 打印文件信息.
				FileHeader fh = a.nextFileHeader();
				while (fh != null) {
					if (fh.isDirectory()) { // 文件夹
						// 如果是中文路径，调用getFileNameW()方法，否则调用getFileNameString()方法，还可以使用if(fh.isUnicode())
						if (existZH(fh.getFileNameW())) {
							fol = new File(dstDirectoryPath + File.separator + fh.getFileNameW());
						} else {
							fol = new File(dstDirectoryPath + File.separator + fh.getFileNameString());
						}
						fol.mkdirs();
					} else { // 文件
						if (existZH(fh.getFileNameW())) {
							out = new File(dstDirectoryPath + File.separator + fh.getFileNameW().trim());
						} else {
							out = new File(dstDirectoryPath + File.separator + fh.getFileNameString().trim());
						}
						try {// 之所以这么写try，是因为万一这里面有了异常，不影响继续解压.
							if (!out.exists()) {
								if (!out.getParentFile().exists()) {// 相对路径可能多级，可能需要创建父目录.
									out.getParentFile().mkdirs();
								}
								out.createNewFile();
							}
							FileOutputStream os = new FileOutputStream(out);
							a.extractFile(fh, os);
							os.close();
						} catch (Exception ex) {
							ex.printStackTrace();
						}
					}
					fh = a.nextFileHeader();
				}
				a.close();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/**
	 * 解压区分xls与img
	 * 
	 * @param srcRarPath(文件路径)
	 * @param dstDirectoryPath(解压路径)
	 * @throws Exception
	 */
	public static void unRarExcelOrImg(String srcRarPath, String dstDirectoryPath) throws Exception {
		if (!srcRarPath.toLowerCase().endsWith(".rar")) {
			log.error("非rar文件！");
			return;
		}
		File dstDiretory = new File(dstDirectoryPath);
		if (!dstDiretory.exists()) {// 目标目录不存在时，创建该文件夹
			dstDiretory.mkdirs();
		}
		File out = null;
		Archive a = null;
		try {
			a = new Archive(new File(srcRarPath));
			if (a != null) {
				a.getMainHeader().print(); // 打印文件信息.
				FileHeader fh = a.nextFileHeader();
				List<String> list = Arrays.asList(new String[] { "png", "jpeg", "gif", "jpg", "bmp" });
				while (fh != null) {
					if (!fh.isDirectory()) {
						if (existZH(fh.getFileNameW())) {
							if (fh.getFileNameW().endsWith(".xls")) {
								out = new File(dstDirectoryPath + File.separator + "excel" + File.separator
										+ fh.getFileNameW().trim());
							} else if (list.contains(fh.getFileNameW().substring(fh.getFileNameW().lastIndexOf(".") + 1)
									.trim().toLowerCase())) {
								out = new File(dstDirectoryPath + File.separator + "img" + File.separator
										+ fh.getFileNameW().trim());
							}
						} else {
							if (fh.getFileNameString().endsWith(".xls")) {
								out = new File(dstDirectoryPath + File.separator + "excel" + File.separator
										+ fh.getFileNameString().trim());
							} else if (list.contains(fh.getFileNameString()
									.substring(fh.getFileNameString().lastIndexOf(".") + 1).trim().toLowerCase())) {
								out = new File(dstDirectoryPath + File.separator + "img" + File.separator
										+ fh.getFileNameString().trim());
							}
						}
						try {// 之所以这么写try，是因为万一这里面有了异常，不影响继续解压.
							if (!out.exists()) {
								if (!out.getParentFile().exists()) {// 相对路径可能多级，可能需要创建父目录.
									out.getParentFile().mkdirs();
								}
								out.createNewFile();
							}
							FileOutputStream os = new FileOutputStream(out);
							a.extractFile(fh, os);
							os.close();
						} catch (Exception ex) {
							ex.printStackTrace();
						}

					}
					fh = a.nextFileHeader();
				}
				a.close();
			}

		} catch (Exception e) {
			e.printStackTrace();
		}

	}

	/*
	 * 
	 * 判断是否是中文
	 * 
	 */

	private static boolean existZH(String str) {
		String regEx = "[\\u4e00-\\u9fa5]";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(str);
		while (m.find()) {
			return true;
		}
		return false;

	}

	public static void main(String[] args) {
		try {
			// unRarExcelOrImg("D:\\hheh\\Saved Pictures.rar", "D:\\hheh\\");
			ZipFiles("D:\\hheh\\excel","D:\\hheh\\img.rar");
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}

	}

}
